package com.wzdigit.wms.basic.service.code.back;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
import javax.annotation.PostConstruct;
import org.apache.dubbo.config.annotation.Reference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.wzdigit.mes.basic.api.BasicDataItemApi;
import com.wzdigit.mes.basic.api.BasicDataItemDetailApi;
import com.wzdigit.mes.basic.api.BasicStaffApi;
import com.wzdigit.mes.basic.dto.DataItemDTO;
import com.wzdigit.mes.basic.dto.DataItemDetailDTO;
import com.wzdigit.mes.basic.dto.StaffDTO;
import com.wzdigit.wms.basic.domain.dtos.mid.IfPostbackDto;
import com.wzdigit.wms.basic.enums.writeback.BackIsErrorRemindEnum;
import com.wzdigit.wms.basic.enums.writeback.BackResultEnum;
import com.wzdigit.wms.basic.mapper.core.mid.IfPostbackMapper;
import com.wzdigit.wms.basic.util.DateUtils;

/**
 * WMS数据回传异常提醒【主线程】
 * 
 * @author Administrator
 *
 */
@Service
public class BackErrorRemindService {
	
	@Autowired
	private IfPostbackMapper ifPostbackMapper;
	
	@Autowired
	private BackErrorRemindThreadService backErrorRemindThreadService;

	@Reference(version = "${dubbo.consumers.basic.staff.api:1.0.0}", check = false, timeout = 300000)
	private BasicStaffApi staffApi;
	
	@Reference(version = "${dubbo.consumers.basic.data.item.api:1.0.0}", check = false, timeout = 300000)
    private BasicDataItemApi dataItemApi;
	
	@Reference(version = "${dubbo.consumers.basic.data.item.detail.api:1.0.0}", check = false, timeout = 300000)
    private BasicDataItemDetailApi dataItemDetailApi;
	
	private static final String BACK_ERROR_REMIND = "BACK_ERROR_REMIND";
	private List<Integer> postbackResultList;
	
    @PostConstruct
    public void initialize() {
    	postbackResultList = new ArrayList<>(4);
		postbackResultList.add(BackResultEnum.BUSINESS_FAIL_STATE.code);
		postbackResultList.add(BackResultEnum.SYSTEM_ERROR_STATE.code);
		postbackResultList.add(BackResultEnum.REPORT_CHECK_FAIL.code);
		postbackResultList.add(BackResultEnum.REPORT_CHECK_ERROR.code);
	}
	
	public void deal() throws Exception {
		Date date = new Date();
		Date beginPostbackTime = DateUtils.getStartTime(date);
		Date endPostbackTime = DateUtils.getEndTime(date);
		List<IfPostbackDto> backFailDataList = ifPostbackMapper.searchFailData(postbackResultList, BackIsErrorRemindEnum.NOT_REMIND.code, beginPostbackTime, endPostbackTime);
		if(backFailDataList.isEmpty()) {
			return;
		}
		
		List<DataItemDTO> systemList = dataItemApi.getDataItemByParentCode(BACK_ERROR_REMIND);
		Map<String, Map<String, List<StaffDTO>>> systemDataMap = new HashMap<>(systemList.size());
		for (DataItemDTO system : systemList) {
			List<DataItemDTO> topicList = dataItemApi.getDataItemByParentCode(system.getItemCode());
			Map<String, List<StaffDTO>> topicDataMap = new HashMap<>(topicList.size());
			for (DataItemDTO topic : topicList) {
				List<DataItemDetailDTO> staffList = dataItemDetailApi.getDataItemDetailByCode(topic.getItemCode());
				List<StaffDTO> staffDTOList = new ArrayList<>(staffList.size());
				for (DataItemDetailDTO staff : staffList) {
					staffDTOList.add(staffApi.getStaffByCode(staff.getItemValue()));
				}
				if(!staffDTOList.isEmpty()) {
					topicDataMap.put(topic.getItemName(), staffDTOList);
				}
			}
			if(!topicDataMap.isEmpty()) {
				systemDataMap.put(system.getItemName(), topicDataMap);
			}
		}
		if(systemDataMap.isEmpty()) {
			return;
		}
		
		CountDownLatch countDownLatch = new CountDownLatch(backFailDataList.size());
		for (IfPostbackDto backFailDto : backFailDataList) {
			Map<String, List<StaffDTO>> topicDataMap = systemDataMap.get(backFailDto.getDestSystem());
			if(topicDataMap == null) {
				countDownLatch.countDown();
			} else {
				List<StaffDTO> staffDTOList = topicDataMap.get(backFailDto.getPostbackTopic());
				if(staffDTOList == null) {
					countDownLatch.countDown();
				} else {
					backErrorRemindThreadService.deal(backFailDto, staffDTOList, countDownLatch);
				}
			}
		}
		countDownLatch.await();
	}
}
